#include "eutranManager.h"
#include "eutranCtrl.h"
#include "common.h"
#include "BbuManager.h"
#include "SnifferManager.h"
#include "OamMessageProtocol.h"
#include "OamManager.h"
#include "EutranConfigData.h"
#include "RrcAsnCodecApi.h"
#ifdef ignore
#undef ignore
#endif
#include <iomanip>
#include <sstream>
#include <iomanip>
#include <stdlib.h>
#include "AutoSnifferCtrl.h"

EutranTimer::EutranTimer()
{
}

EutranTimer* EutranTimer::instance()
{
    static EutranTimer instance_;
    return &instance_;
}

bool EutranTimer::initialize()
{
    return true;
}

bool EutranTimer::queue(uint32_t timerVal, EutranTimerElementInterface* element)
{
    if( timerVal==0 || element==NULL )
    {
        return false;
    }

    if( elements_.find(element)==elements_.end() )
    {
        elements_.insert(TimerElementType::value_type(element, timerVal));
        element->isQueue_ = true;
    }

    return true;
}

bool EutranTimer::dequeue(EutranTimerElementInterface* element)
{
    if( element==NULL )
    {
        return false;
    }

    elements_.erase(element);
    element->isQueue_ = false;
    return true;
}

void EutranTimer::handleTick()
{
    for(TimerElementType::iterator it=elements_.begin(); it!=elements_.end(); )
    {
        it->second--;
        if( it->second==0 )
        {
            EutranTimerElementInterface* hook = it->first;
            elements_.erase(it++);
            
            if( hook!=NULL )
            {
                hook->isQueue_ = false;
                hook->callback();
            }
        }
        else
        {
            it++;
        }
    }
}

WrapperCmdPara::WrapperCmdPara():
paraType_(0),
paraLength_(0),
value_(NULL)
{
};

WrapperCmdPara::WrapperCmdPara(uint32_t type, uint32_t length, uint8_t* value):
paraType_(type),
paraLength_(length),
value_(value)
{
    innerValue.v32 = 0;
}

WrapperCmdPara::WrapperCmdPara(uint32_t type, uint8_t value):
paraType_(type),
paraLength_(sizeof(int8_t)),
value_(&(innerValue.v8))
{
    innerValue.iv8 = value;
}

WrapperCmdPara::WrapperCmdPara(uint32_t type, int8_t value):
paraType_(type),
paraLength_(sizeof(int8_t)),
value_(reinterpret_cast<uint8_t*>(&(innerValue.iv8)))
{
    innerValue.iv8 = value;
}

WrapperCmdPara::WrapperCmdPara(uint32_t type, uint16_t value):
paraType_(type),
paraLength_(sizeof(uint16_t)),
value_(reinterpret_cast<uint8_t*>(&(innerValue.v16)))
{
    innerValue.v16 = value;
}

WrapperCmdPara::WrapperCmdPara(uint32_t type, uint32_t value):
paraType_(type),
paraLength_(sizeof(uint32_t)),
value_(reinterpret_cast<uint8_t*>(&(innerValue.v32)))
{
    innerValue.v32 = value;
}

WrapperCmdPara::WrapperCmdPara(uint32_t type, int32_t value):

paraType_(type),

paraLength_(sizeof(int32_t)),

value_(reinterpret_cast<uint8_t*>(&(innerValue.i32)))

{
    
    innerValue.i32 = value;

}



WrapperCmdPara::WrapperCmdPara(uint32_t type, uint64_t value):
paraType_(type),
paraLength_(sizeof(uint64_t)),
value_(reinterpret_cast<uint8_t*>(&(innerValue.v64)))
{
    innerValue.v64 = value;
}

ReliableMessageElement::ReliableMessageElement(uint8_t* buf, uint32_t len, uint32_t seqNo, uint8_t slotId):
buf_(NULL),
length_(0),
tick_(5),
seqNo_(seqNo),
slotId_(slotId)
{
    if( buf!=NULL && len!=0 )
    {
        length_ = len;
        buf_ = new uint8_t[length_];
        if( buf==NULL )
        {
            EMLogError("Fail to allocate buffer[len=%d]", length_);
            return;
        }

        memcpy(buf_, buf, length_);
    }
}

ReliableMessageElement::~ReliableMessageElement()
{
    if( buf_!=NULL )
    {
        delete [] buf_;
        buf_ = NULL;
    }

    length_ = 0;
}

void ReliableMessageElement::getMsgBuffer(uint8_t*& buf, uint32_t& length)
{
    buf = buf_;
    length = length_;
}

uint32_t& ReliableMessageElement::getTickRef()
{
    return tick_;
}

uint32_t ReliableMessageElement::getSeqNo()
{
    return seqNo_;
}

uint8_t ReliableMessageElement::getSlotId()
{
    return slotId_;
}

MODREG EutranMgr::modEutranmgrInfo_= {MODULE_EUTRAN_SNIFFER, true, false, 1000, (char*)"eutran"};

EutranMgr::EutranMgr():
rcvThreadOk(true),
processingMsgSrcId_(0),
processingMsgTypeId_(0),
cmdTimeoutVal_(60),
heartBeatVal_(5),
cmdTimeoutHandler_(this, &EutranMgr::handleCmdProcessTimeout),
TimerHeartBeat_(this, &EutranMgr::timerHeartBeat)
{
    memset(&processingCmdHdr_, 0, sizeof(processingCmdHdr_));
}

EutranMgr* EutranMgr::instance()
{
    static EutranMgr instance_;
    return &instance_;
}

bool EutranMgr::initialize()
{
    if( !BbuManagerPtr->initialize() )
    {
        EMLogError("Fail to initialize BbuManager");
        return false;
    }

    if( !SnifferMgrPtr->initialize() )
    {
        EMLogError("Fail to initialize SnifferMgr");
        return false;
    }
    pthread_mutex_init(&mutex, NULL);
    EutranTimerPtr->queue(heartBeatVal_, &TimerHeartBeat_);

    uint8_t data[65535] = {0};
    uint32_t dataLength = 29;
    RrcMessageType msgType;
    if( !RrcAsnCodecApi::decodeBcchDlSchMessageType(data, dataLength, msgType) )
    {
        

        std::stringstream ss;
        ss << "Data: len[0x" << std::hex << dataLength << "]: ";
        for(uint32_t i=0; i<dataLength; i++)
        {
            ss << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<uint32_t>(data[i]) << " ";
        }
        return false;
    }
    return true;
    return true;
}

void EutranMgr::setThreadStat(bool IsOK)
{
    pthread_mutex_lock(&mutex);
    rcvThreadOk = IsOK;
    pthread_mutex_unlock(&mutex);   
}

bool EutranMgr::getRcvThreadStat()
{
    bool alive = false;
    pthread_mutex_lock(&mutex);
    alive = rcvThreadOk;
    rcvThreadOk = false;
    pthread_mutex_unlock(&mutex); 
    return alive; 
}

bool EutranMgr::setBbuIp(uint8_t slotId, std::string& ipAddr, uint16_t port)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES )
    {
        EMLogError("Slot id[%d] is out of range", static_cast<uint32_t>(slotId));
        return false;
    }

    EMLogInfo("Set BBU[%d] ip[%s, %d]", static_cast<uint32_t>(slotId), ipAddr.c_str(), port);

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to found BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        return false;
    }

    bbu->getInstance().setPeerAddress(ipAddr.c_str(), port);
    responseSuccess();
        
    return true;
}

bool EutranMgr::setRxPower(uint8_t slotId, uint8_t rxPwer)
{
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return true;
    }

    if( rxPwer>MAX_RX_POWER )
    {
        EMLogError("RX power[%d] is out of range", rxPwer);
        responseFailure();
        return true;
    }

    EutranConfigDataPtr->setRxPower(slotId, rxPwer);

    std::set<uint32_t> idOfActive;
    if( slotId==0 )
    {
        BbuManagerPtr->getIdOfActiveBbus(idOfActive);
    }
    else
    {
        idOfActive.insert(slotId);
    }

    bool isAllSuccess = true;
    for(std::set<uint32_t>::iterator it=idOfActive.begin(); it!=idOfActive.end(); it++)
    {
        uint8_t slotId = *it;
        BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
        if( bbu==NULL )
        {
            EMLogError("Fail to get BBU from slot-id[%d]", *it);
            continue;
        }
        if( !bbu->getInstance().isActive() )
        {
            EMLogError("BBU[%d]: is deactive", bbu->getInstance().getSlotId());
            continue;
        }

        uint8_t rxPwer = EutranConfigDataPtr->getRxPower(slotId);
        if( !bbu->buildAndSendRxPower(rxPwer) )
        {
            EMLogError("Fail to send RxPower to BBU[%d]", bbu->getInstance().getSlotId());
            isAllSuccess = false;
        }
    }

    if( isAllSuccess )
    {
        responseSuccess();
    }
    else
    {
        responseFailure();
    }
    return true;
}

bool EutranMgr::setTxPowerDb(uint8_t slotId, int8_t txPwerDb)
{
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return true;
    }
    
    EutranConfigDataPtr->setTxPowerDb(slotId, txPwerDb);

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return true;
    }

    if( (!bbu->getInstance().isActive()) || (!bbu->isWorking()))
    {
        EMLogInfo("bbu not active so save TXpowerDb slot-id[%d]", static_cast<uint32_t>(slotId));
        responseSuccess();
        return true;
    }
    if( !bbu->buildAndSendTxPowerDb(txPwerDb) )
    {
        EMLogError("Fail to send TxPower to BBU[%d]", bbu->getInstance().getSlotId());
        responseFailure();
        return true;
    }

    return true;
}

void EutranMgr::processPmRestart()
{
    processingMsgSrcId_ = 0;
    EutranTimerPtr->dequeue(&cmdTimeoutHandler_);
}

void EutranMgr::cfgRtParameter(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t slotId = 0;

    OamMessageProtocol_RunTimeParaCfg rtCfg;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slot-id: %d", static_cast<uint32_t>(slotId));
        }
        else if( paraType==PARA_TYPE_EUTRAN_IS_RAN_SHARE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            uint8_t v8 = atoi(value);
            EMLogInfo("isRanShare is %d", static_cast<uint32_t>(v8));
            
            rtCfg.packRanSharePara(v8!=0);
        }
        else if( paraType==PARA_TYPE_EUTRAN_IS_RAN_SHARE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            uint8_t v8 = atoi(value);
            EMLogInfo("isRanShare is %d", static_cast<uint32_t>(v8));
            
            rtCfg.packRanSharePara(v8!=0);
        }
        else if( paraType==PARA_TYPE_EUTRAN_NAS_REJECT_CAUSE_PAIR_STR )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            std::string paraStr(value);

            EMLogInfo("CAUSE_PAIR_STR is %s", paraStr.c_str());

            if(paraStr.length()<3 )
            {
                EMLogError("Invalid para");
                continue;
            }

            uint32_t v32 = 0;

            std::string typeStr = paraStr.substr(0, 1);
            std::stringstream ss;
            ss << typeStr;

            uint8_t type = 0;
            ss >> v32;
            type = v32;
            ss.clear();
            ss.str("");

            std::string causeStr = paraStr.substr(2, paraStr.length()-2);
            ss << causeStr;
            uint8_t cause = 0;
            ss >> v32;
            cause = v32;
            
            EMLogInfo("type[%d]; cause[%d]", static_cast<uint32_t>(type), static_cast<uint32_t>(cause));
            rtCfg.packNasRejectCause(type, cause);
        }
    }

    std::vector < WrapperCmdPara > responseParas;
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return ;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id=%d] is deactive", bbu->getInstance().getSlotId());
        responseFailure();
        return ;
    }

    if( !bbu->sendRtParaCfg(rtCfg) )
    {
        responseFailure();
        return ;
    }
}

void EutranMgr::processStdTxPowerDbGetMessage(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t slotId = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slot-id: %d", static_cast<uint32_t>(slotId));
        }
    }

    std::vector < WrapperCmdPara > responseParas;
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return ;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id=%d] is deactive", bbu->getInstance().getSlotId());
        responseFailure();
        return ;
    }

    if( !bbu->buildAndSendStdTxPowerDbGet() )
    {
        responseFailure();
        return ;
    }
}

void EutranMgr::processStdTxPowerGetMessage(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t slotId = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slot-id: %d", static_cast<uint32_t>(slotId));
        }
    }

    std::vector < WrapperCmdPara > responseParas;
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return ;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id=%d] is deactive", bbu->getInstance().getSlotId());
        responseFailure();
        return ;
    }

    if( !bbu->buildAndSendStdTxPowerDbGet() )
    {
        responseFailure();
        return ;
    }
}

void EutranMgr::processStdTxPowerCfgMessage(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t slotId = 0;
    uint8_t stdTxPower = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slot-id: %d", static_cast<uint32_t>(slotId));
        }
        else if( paraType==PARA_TYPE_EUTRAN_STD_TX_POWER )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            stdTxPower = atoi(value);
            EMLogInfo("stdTxPower: %d", static_cast<uint32_t>(stdTxPower));
        }
    }

    std::vector < WrapperCmdPara > responseParas;
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return ;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id=%d] is deactive", bbu->getInstance().getSlotId());
        responseFailure();
        return ;
    }

    if( !bbu->buildAndSendStdTxPower(stdTxPower) )
    {
        responseFailure();
        return ;
    }
}

void EutranMgr::processBbuMessage(uint8_t* data, uint32_t dataLength, in_addr_t peerAddr)
{
    if( data==NULL )
    {
        EMLogError("Data is NULL");
        return;
    }

    std::stringstream ss;
    ss << "len[" << dataLength << "]: ";
    for(uint32_t i=0; i<dataLength; i++)
    {
        ss << "0x" << std::hex << std::setw(2) << std::setfill('0') << static_cast<uint32_t>(data[i]) << " ";
    }

    if( dataLength<2 || (data[1]!=NmmToX86Protocol_Signal::HEARBEAT_ACK && data[1]!=NmmToX86Protocol_Signal::HEARBEAT) )
    { 
        EMLogInfo("Receive epcsim message from ip[0x%x]: %s", peerAddr, ss.str().c_str());
    }

    TlvMessage tlvMsg(data, dataLength);
    switch(tlvMsg.getProtocolType())
    {
        case NmmToX86Protocol_Signal::TLV_PROTOCOL_NUMBER:
        {
            switch(tlvMsg.getSignalType())
            {
                case NmmToX86Protocol_Signal::UE_REDIRECT_RSP:
                case NmmToX86Protocol_Signal::INIT_NOTIFICATION:
                case NmmToX86Protocol_Signal::HEARBEAT_ACK:
                case NmmToX86Protocol_Signal::CELL_CONFIG_RSP:
                case NmmToX86Protocol_Signal::CELL_UPDATE_RSP:
                case NmmToX86Protocol_Signal::HEARBEAT:
                {
                    OamManagerPtr->processOamMessage(tlvMsg, peerAddr);
                    break;
                }
                case NmmToX86Protocol_Signal::SNIFFER_START_RSP:
                case NmmToX86Protocol_Signal::SNIFFER_STOP_RSP:
                case NmmToX86Protocol_Signal::SNIFFER_RESULT_REPORT:
                case NmmToX86Protocol_Signal::SNIFFER_RESULT_REPORT_END:
                case NmmToX86Protocol_Signal::SNIFFER_REST_RSP:
                case NmmToX86Protocol_Signal::NMM_STATUS_REPORT:
                {
                    EMLogDebug("Receive NMM msg type[%d]", static_cast<uint32_t>(tlvMsg.getSignalType()))
                    BbuCtrl* bbu = BbuManagerPtr->getBbu(peerAddr);
                    if( bbu==NULL )
                    {
                        EMLogWarning("Fail to get BBU from ip[0x%x]", ntohl(peerAddr));
                        break;
                    }
                    if( !bbu->getInstance().isActive() )
                    {
                        EMLogWarning("BBU from ip[0x%x] is not active", ntohl(peerAddr));
                        break;
                    }
                    SnifferMgrPtr->handleNmmMessage(tlvMsg, *bbu);
                    break;
                }
                case NmmToX86Protocol_Signal::UEID_REPORT:
                {
                    BbuCtrl* bbu = BbuManagerPtr->getBbu(peerAddr);
                    if( bbu==NULL )
                    {
                        EMLogWarning("Fail to get BBU from ip[0x%x]", ntohl(peerAddr));
                        break;
                    }
                    NmmToX86Protocol_UeidReport ueId(tlvMsg);
                    uint32_t recvSeqNo = 0;
                    if( !ueId.unpackSeqNum(recvSeqNo) )
                    {
                        EMLogWarning("Fail to unpack seq number");
                    }
                    
                    NmmToX86Protocol_UeidReportRsp rsp;
                    rsp.packSeqNum(recvSeqNo);
                    if( !bbu->getInstance().sendMessage(rsp.getMessage()) )
                    {
                        EMLogError("Fail to send UeidReportRsp");
                    }

                    processUeId(bbu->getInstance().getSlotId(), data, dataLength);
                    break;
                }
                case NmmToX86Protocol_Signal::LTE_SCAN_RESULT_RSP:
                {
                    BbuCtrl* bbu = BbuManagerPtr->getBbu(peerAddr);
                    if( bbu==NULL )
                    {
                        EMLogWarning("Fail to get BBU from ip[0x%x]", ntohl(peerAddr));
                        break;
                    }
                    NmmToX86Protocol_LteScanResultRsp scanRes(tlvMsg);
                    uint32_t recvSeqNo = 0;
                    if( !scanRes.unpackSeqNum(recvSeqNo) )
                    {
                        EMLogWarning("Fail to unpack seq number");
                    }

                    processScanResult(bbu->getInstance().getSlotId(), data, dataLength);
                    break;
                }
                default:
                {
                    EMLogWarning("Unkown NMM signal type: %d", static_cast<uint32_t>(tlvMsg.getSignalType()));
                    break;
                }
            }
            break;
        }
        case OamMessageProtocol_Signal::TLV_PROTOCOL_NUMBER:
        {
            OamManagerPtr->processOamMessage(tlvMsg, peerAddr);
            break;
        }
        default:
        {
            EMLogWarning("Unkown protocol type: %d", static_cast<uint32_t>(tlvMsg.getProtocolType()));
            break;
        }
    }
}

void EutranMgr::setSnifferResultReportStrategy(uint8_t strategy)
{
    if( strategy==0 )
    {
        SnifferMgrPtr->setSnifferReportStrategy(RPT_ALL);
    }
    else
    {
        SnifferMgrPtr->setSnifferReportStrategy(RPT_EXCLUDE_ONLY_IN_RSSI_MEAS);
    }
}

void EutranMgr::setAutoCfgCellFlag(bool isCfg)
{
    SnifferMgrPtr->setAutoCfgCellFlag(isCfg);
}

void EutranMgr::initConfigComp(uint8_t slotId)
{
    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )

    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        return;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id] is deactive", static_cast<uint32_t>(slotId));
        return;
    }

    bbu->buildAndSendInitCfg();
}

void EutranMgr::saveMsgCmdCodeAndSrcID(const PMSGHEADER srcID, PCMDHEADER hdr)
{
    if( hdr==NULL )
    {
        EMLogError("PCMDHEADER is NULL");
        return;
    }
    processingMsgSrcId_ = srcID->srcID;
    processingMsgTypeId_ = srcID->msgType;
    processingCmdHdr_.cmdIndex = hdr->cmdIndex;
    processingCmdHdr_.cmdCode = hdr->cmdCode;
    processingCmdHdr_.cmdType = hdr->cmdType;
    
    if (processingCmdHdr_.cmdCode == CMD_CODE_EUTRAN_BBU_UPGRADE)
    {
        if( !EutranTimerPtr->queue(300, &cmdTimeoutHandler_) )
        {
            EMLogError("Fail to queue cmdTimeoutHandler_");
        }        
    }
    else
    {
        if( !EutranTimerPtr->queue(cmdTimeoutVal_, &cmdTimeoutHandler_) )
        {
            EMLogError("Fail to queue cmdTimeoutHandler_");
        }
    }
}

void EutranMgr::reportInfo(uint16_t cmdCode, const std::vector<WrapperCmdPara>& paraArray)
{
    reportToModule(MODULE_INTF, cmdCode, paraArray);
}

void EutranMgr::reportEvent(uint16_t cmdCode, const std::vector<WrapperCmdPara>& paraArray)
{
    reportToModule(MODULE_SYSTEM, cmdCode, paraArray);
}

void EutranMgr::reportUeId(uint16_t cmdCode, const std::vector<WrapperCmdPara>& paraArray)
{
    reportToModule(MODULE_DATAPRO, cmdCode, paraArray);
}

void EutranMgr::reportSnifferResult(uint16_t cmdCode, const std::vector<WrapperCmdPara>& paraArray)
{
    reportToModule(MODULE_INTF, CMD_EVT_EUTRAN_SNIFFER_RESULT, paraArray);
}

void EutranMgr::reportScanResult(uint16_t cmdCode, const std::vector<WrapperCmdPara>& paraArray)
{
    reportToModule(MODULE_INTF, CMD_EVT_EUTRAN_LTE_SCAN_RES, paraArray);
}

void EutranMgr::responseSuccess()
{
    if( !isProcessingCmd() )
    {
        return;
    }
    std::vector < WrapperCmdPara > responseParas;
    responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_SUCCESS)));
    responseToSrcModule((processingCmdHdr_.cmdType | 0x10), responseParas);
}

void EutranMgr::responseFailure()
{
    if( !isProcessingCmd() )
    {
        return;
    }
    std::vector < WrapperCmdPara > responseParas;
    responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_FAILED)));
    responseToSrcModule((processingCmdHdr_.cmdType | 0x10), responseParas);
}

void EutranMgr::responseToSrcModule(uint16_t cmdType, const std::vector<WrapperCmdPara>& paraArray)
{
    if( processingMsgSrcId_==0 )
    {
        EMLogError("processingMsgSrcId_ should not be 0");
        return;
    }
    
    responseToModule(processingMsgSrcId_, processingMsgTypeId_, cmdType, processingCmdHdr_.cmdCode, processingCmdHdr_.cmdIndex, paraArray);

    processingMsgSrcId_ = 0;
    EutranTimerPtr->dequeue(&cmdTimeoutHandler_);
}

void EutranMgr::reportToModule(uint16_t dstId, uint16_t cmdCode, const std::vector<WrapperCmdPara>& paraArray) 
{
    responseToModule(dstId, MSG_TYPE_COMMAND, CMD_EVENT, cmdCode, 0, paraArray);
}

void EutranMgr::responseToModule(uint16_t dstId, uint16_t msgType, uint16_t cmdType, uint16_t cmdCode, uint16_t cmdIndex, const std::vector<WrapperCmdPara>& paraArray)
{
    if( paraArray.empty() )
    {
        CM_SendMsg_noPara(dstId, MODULE_EUTRAN_SNIFFER, msgType, cmdType, cmdCode, cmdIndex);
    }
    else if( paraArray.size()==1 )
    {
        CM_SendMsg_1Para(dstId, MODULE_EUTRAN_SNIFFER, msgType, cmdType, cmdCode, cmdIndex, paraArray[0].paraType_, paraArray[0].paraLength_, paraArray[0].value_);
    }
    else if( paraArray.size()==2 )
    {
        CM_SendMsg_2Para(dstId, MODULE_EUTRAN_SNIFFER, msgType, cmdType, cmdCode, cmdIndex, 
                         paraArray[0].paraType_, paraArray[0].paraLength_, paraArray[0].value_,
                         paraArray[1].paraType_, paraArray[1].paraLength_, paraArray[1].value_);
    }
    else if( paraArray.size()==3 )
    {
        CM_SendMsg_3Para(dstId, MODULE_EUTRAN_SNIFFER, msgType, cmdType, cmdCode, cmdIndex, 
                         paraArray[0].paraType_, paraArray[0].paraLength_, paraArray[0].value_,
                         paraArray[1].paraType_, paraArray[1].paraLength_, paraArray[1].value_,
                         paraArray[2].paraType_, paraArray[2].paraLength_, paraArray[2].value_);
    }
    else
    {
        U64 msgbuff[MSG_BUFF_SIZE/8] = {0};
        uint32_t totalLength = sizeof(msgbuff);
        
        PMSGHEADER pMsgHeader =(PMSGHEADER) msgbuff;
        PCMDHEADER pCmdHeader = (PCMDHEADER)( ((U8*)msgbuff) + sizeof(MSGHEADER) );

        totalLength = totalLength - sizeof(MSGHEADER) + sizeof(CMDHEADER);
        
        PPARAM pParam = (PPARAM)(pCmdHeader + 1);
        U8 *pValue = NULL;

        pMsgHeader->dstID = dstId;
        pMsgHeader->srcID = MODULE_EUTRAN_SNIFFER;
        pMsgHeader->mType = get_mtype(pMsgHeader->dstID);
        pMsgHeader->msgType = msgType;

        pCmdHeader->cmdType = cmdType;
        pCmdHeader->cmdCode = cmdCode;
        pCmdHeader->cmdIndex = cmdIndex;
    
        pCmdHeader->cmdLength = 0; 

        for( size_t i=0; i<paraArray.size(); i++)
        {
            uint32_t len = CM_paraPackPara(&pParam, paraArray[i].paraType_, paraArray[i].paraLength_, &pValue);
            pCmdHeader->cmdLength += len;
            memcpy(pValue, paraArray[i].value_, paraArray[i].paraLength_);

            if( totalLength < len )
            {
                EMLogError("Msg with over length, fail to pack");
                processingMsgSrcId_ = 0;
                EutranTimerPtr->dequeue(&cmdTimeoutHandler_);
                
                return;
            }
            totalLength -= len;
        }
    
        pMsgHeader->msgLength = sizeof(MSGHEADER) + sizeof(CMDHEADER) + pCmdHeader->cmdLength;
        CM_sendMsg(pMsgHeader,pCmdHeader);
    }
}


void EutranMgr::reqGpsState(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t slotId = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slot-id: %d", static_cast<uint32_t>(slotId));
        }
    }

    std::vector < WrapperCmdPara > responseParas;
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return ;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id=%d] is deactive", bbu->getInstance().getSlotId());
        responseFailure();
        return ;
    }

    if( !bbu->buildAndSendGpsStateReq() )
    {
        responseFailure();
        return ;
    }
}

void EutranMgr::enableInterference(PPARAM pParam, uint32_t len)
{
    uint8_t slotId = 0;
    bool isEnable = false;
    
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
        else if( PARA_TYPE_EUTRAN_INTERFERENCE_ENABLE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            uint8_t u8 = atoi(value);
            EMLogInfo("isEnable is %d", static_cast<uint32_t>(u8));

            if( u8!=0 )
            {
                isEnable = true;
            }
        }
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->buildAndSendInterferenceEnable(isEnable) )
    {
        responseFailure();
    }
    else
    {
        responseSuccess();
    }
}

void EutranMgr::scanLte(PPARAM pParam, uint32_t len)
{
    EMLogInfo("scan lte");

    uint8_t slotId = 0;
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->buildAndSendScanReq() )
    {
        responseFailure();
    }
}

//void EutranMgr::startSnifferManual(const std::vector<uint8_t>& bandList,
//                                        const std::vector<EarfcnRangeType>& earfcnRange, 
//                                        const std::vector<uint16_t>& pciList)
void EutranMgr::startSnifferManual(PPARAM pParam, uint32_t len)                                       
{
    std::vector < WrapperCmdPara > responseParas;
    
    std::vector<uint16_t> pcilist;
    std::vector< EarfcnRangeType > earfcnList;
    std::vector<uint8_t> bandList;
    uint16_t rssi = 100;
    uint32_t autoCfgCell = 0;
    uint32_t rptStrategy = 1;
    uint8_t slotId = 0;
                        
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    bool isParaValid = true;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_RPT_RESULT_STRATEGY )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            rptStrategy = atoi(value);
        }
        else if( paraType==PARA_TYPE_EUTRAN_AUTO_CONFIG_CELL )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            autoCfgCell = atoi(value);

            EMLogInfo("autoCfgCell=%d", autoCfgCell);
        }
        else if( paraType==PARA_TYPE_EUTRAN_SNIFFER_RSSI )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            rssi = atoi(value);
        }
        else if( paraType==PARA_TYPE_EUTRAN_SNIFFER_BAND )
        {
            for(uint32_t i=0; i<paraLength; i++)
            {
                bandList.push_back(paraValue[i]);
            }
        }
        else if(paraType==PARA_TYPE_EUTRAN_SNIFFER_EARFCN_RANGE )
        {
            if( paraLength%(2*sizeof(uint16_t))!=0 )
            {
                EMLogError("Invalid earfcn parameter length[%d]", paraLength);
                isParaValid = false;
                break;
            }
            uint16_t* p16 = reinterpret_cast<uint16_t*>(paraValue);
            for(uint32_t i=0; i<paraLength/2; )
            {
                uint16_t lowArfcn = p16[i++];
                uint16_t upArfcn = p16[i++];
                earfcnList.push_back(EarfcnRangeType(lowArfcn, upArfcn));
            }
        }
        else if(paraType==PARA_TYPE_EUTRAN_SNIFFER_PCI_LIST )
        {
            if( paraLength%sizeof(uint16_t)!=0 )
            {
                EMLogError("Invalid pcilist parameter length[%d]", paraLength);
                isParaValid = false;
                break;
            }
            uint16_t* p16 = reinterpret_cast<uint16_t*>(paraValue);
            for(uint32_t i=0; i<paraLength/2; i++)
            {
                uint16_t pci = p16[i];
                pcilist.push_back(pci);
            }
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
        else
        {
            EMLogError("Unknown paraType[%d]", paraType);
            isParaValid = false;
        }
        if( !isParaValid )
        {
            EMLogError("paraType[0x%x] is invalid", paraType);
            
            responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_FAILED)));
            responseParas.push_back(WrapperCmdPara(PARA_TYPE_ERROR_CODE, static_cast<uint32_t>(PARA_VALUE_ERROR_INVALID_PARAVALUE)));
            responseToSrcModule(CMD_SET_RESPONSE, responseParas);
            break;
        }
    }

    if( !(isParaValid && (!bandList.empty()||!earfcnList.empty())) )
    {
        EMLogError("Invalid parameter");
        responseFailure();
        return;
    }
                  
    std::vector<EarfcnRangeType> arfcnRange;
    generageArfcnRange(arfcnRange, bandList, earfcnList);

    if( arfcnRange.empty() )
    {
        EMLogError("arfcnRange is empty");
        responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_FAILED)));
        responseToSrcModule(CMD_SET_RESPONSE, responseParas);
        return ;
    }

    setSnifferResultReportStrategy(rptStrategy);
    if( autoCfgCell==0 )
    {
        setAutoCfgCellFlag(false);
    }
    else
    {
        setAutoCfgCellFlag(true);
    }
    EutranConfigDataPtr->setRssiThreshold(slotId, rssi);

    if( !SnifferMgrPtr->startSniffer(OAM_SNF_TRIGGER, slotId, arfcnRange, &pcilist) )
    {
        EMLogError("Fail to start sniffer");
        responseFailure();
    }
}

void EutranMgr::reportSnifferResult(PPARAM pParam, uint32_t len)

{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    bool isParaValid = true;

    uint8_t slotId = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
        else
        {
            EMLogError("Unknown paraType[%d]", paraType);
            isParaValid = false;
        }
    }

    std::vector<WrapperCmdPara> paras;
    if( SnifferMgrPtr->isSniffering(slotId))
    {
        EMLogInfo("SNIFFER is busy");
        paras.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_SLOT_ID, slotId));
        paras.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_SNIFFER_BUSY, 0, NULL));
        responseToSrcModule(CMD_GET_RESPONSE, paras);
    }
    else
    {
        uint8_t buf[65535];
        memset(buf, 0, sizeof(buf));

        uint8_t* ptr = &buf[0];
        uint32_t length = 0;
        SnifferMgrPtr->packSnifferResult(slotId, ptr, length);

        if( length==0 )
        {
            paras.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_SNIFFER_EMPTY_RESULT, 0, NULL));
            
        }
        else
        {
            paras.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_SLOT_ID, slotId));
            paras.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_SNIFFER_RESULT, length, buf));
        }
        
        EutranMgrPtr->responseToSrcModule(CMD_GET_RESPONSE, paras);
    }
    
}

void EutranMgr::ueIdFilter(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;

    uint8_t slotId = 0;
    bool isEnable = false;
    uint32_t timer = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
        else if( paraType==PARA_TYPE_EUTRAN_UEID_FILTER_SWITCH )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            isEnable = atoi(value);
            EMLogInfo("isEnable is %d", isEnable);
        }
        else if( paraType==PARA_TYPE_EUTRAN_UEID_FILTER_TIMER )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            timer = atoi(value);
            EMLogInfo("timer is %d", timer);
        }
    }

    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }

    if( !bbu->getInstance().isActive() )
    {
        EMLogError("BBU[slot-id=%d] is deactive", bbu->getInstance().getSlotId());
        responseFailure();
        return ;
    }

    if( isEnable )
    {
        if ( !bbu->buildAndSendUeIdFilter(isEnable, &timer))
        {
            responseFailure();
        }
    }
    else
    {
        if ( !bbu->buildAndSendUeIdFilter(isEnable, NULL))
        {
            responseFailure();
        }
    }

    EMLogInfo("UEID filter: enable[%d], timer[%d]", isEnable, timer);
}

void EutranMgr::cfgAutoSniffer(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;

    uint8_t slotId = 0;
    uint16_t snfDay = 0;
    std::string timeStr;
    uint16_t rssi = 0;
    bool isParaValid = true;
    uint16_t ulArfcn = 0;
    std::vector< EarfcnRangeType > earfcnList;
    uint32_t operCode = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_AUTO_SNF_OPER_CODE )
        {
            operCode = *(reinterpret_cast<uint32_t*>(paraValue));
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
        else if( paraType==PARA_TYPE_EUTRAN_AUTO_SNF_DAY )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            snfDay = atoi(value);
            EMLogInfo("snfDay is %d", static_cast<uint32_t>(snfDay));
        }
        else if( paraType==PARA_TYPE_EUTRAN_AUTO_SNF_TIME )
        {
            timeStr.assign(reinterpret_cast<char*>(paraValue), paraLength);
            EMLogInfo("SNF time is %s", timeStr.c_str());
        }
        else if( paraType==PARA_TYPE_EUTRAN_SNIFFER_RSSI )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            rssi = atoi(value);
            EMLogInfo("rssi is %d", rssi);
        }
        else if(paraType==PARA_TYPE_EUTRAN_SNIFFER_EARFCN_RANGE )
        {
            if( paraLength%(2*sizeof(uint16_t))!=0 )
            {
                EMLogError("Invalid earfcn parameter length[%d]", paraLength);
                isParaValid = false;
                break;
            }
            uint16_t* p16 = reinterpret_cast<uint16_t*>(paraValue);
            for(uint32_t i=0; i<paraLength/2; )
            {
                uint16_t lowArfcn = p16[i++];
                uint16_t upArfcn = p16[i++];
                earfcnList.push_back(EarfcnRangeType(lowArfcn, upArfcn));
            }
        }
        else if( paraType==PARA_TYPE_EUTRAN_UL_ARFCN )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            ulArfcn = atoi(value);
            EMLogInfo("ulArfcn is %d", ulArfcn);
        }
    }

    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return;
    }

    if( operCode==PARA_VALUE_EUTRAN_AUTO_SNF_REQ )
    {
        EMLogInfo("PARA_VALUE_EUTRAN_AUTO_SNF_REQ");
        std::stringstream ss;
        AutoSnifferCtrl* autoSnfCtrl = SnifferMgrPtr->autoSnfCtrls_[slotId-1];
        if( autoSnfCtrl->isActive() )
        {
            ss << "Auto sniffer is ongoing.";
        }
        
        if( autoSnfCtrl->strategy_==NULL )
        {
            EMLogInfo("BBU[%d]: strategy is NULL pointer");
            ss << "No auto sniffer config.";
        }
        else
        {
            AutoSnfByTime* snfTime = dynamic_cast<AutoSnfByTime*>(autoSnfCtrl->strategy_);
            if( autoSnfCtrl->strategy_==NULL )
            {
                EMLogError("BBU[%d]: strategy is NULL pointer");
                ss << "No auto sniffer config.";
                return;
            }
            ss << "hour: " << static_cast<uint32_t>(snfTime->hour_) << "; min: " << static_cast<uint32_t>(snfTime->min_);
        }

        std::string strInfo = ss.str();
        std::vector < WrapperCmdPara > responseParas;
        responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_SUCCESS)));
        responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_AUTO_SNF_INFO_STR, strInfo.length(), reinterpret_cast<uint8_t*>(const_cast<char*>(strInfo.c_str()))));
        responseToSrcModule((processingCmdHdr_.cmdType | 0x10), responseParas);
        return;
    }
    else if( operCode==PARA_VALUE_EUTRAN_AUTO_SNF_DEL )
    {
        EMLogInfo("PARA_VALUE_EUTRAN_AUTO_SNF_DEL");
        if( SnifferMgrPtr->delAutoSnfCfg(slotId) )
        {
            responseSuccess();
        }
        else
        {
            responseFailure();

        }
        return;
    }

    if( !isParaValid )
    {
        EMLogError("Invalid parameter");
        EutranMgrPtr->responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( FDD==bbu->getInstance().getDuplexMode() )
    {
        if( ulArfcn==0 )
        {
            EMLogError("No UL-ARFCN specified");
            responseFailure();
            return;
        }
        bbu->setWorkingUlArfcn(ulArfcn);
    }
                  
    std::vector<EarfcnRangeType> arfcnRange;
    std::vector<uint8_t> bandList;
    generageArfcnRange(arfcnRange, bandList, earfcnList);

    if( arfcnRange.empty() )
    {
        EMLogError("arfcnRange is empty");
        EutranMgrPtr->responseFailure();
        return ;
    }

    uint8_t hour = 0;
    uint8_t min = 0;
    if( !parseTime(timeStr, hour, min) )
    {
        EMLogError("Fail to parse time parameter");

        EutranMgrPtr->responseFailure();
        return ;
    }

    setSnifferResultReportStrategy(RPT_EXCLUDE_ONLY_IN_RSSI_MEAS);
    setAutoCfgCellFlag(true);  
    EutranConfigDataPtr->setRssiThreshold(slotId, rssi);

    if( !SnifferMgrPtr->startAutoSnf(slotId, rssi, arfcnRange, snfDay, hour, min) )
    {
        EMLogError("Fail to start sniffer");
        EutranMgrPtr->responseFailure();
        return;
    }

    EMLogInfo("Success to start auto sniffer");
    EutranMgrPtr->responseSuccess();
}

bool EutranMgr::parseTime(std::string para, uint8_t& hour, uint8_t& min)
{
    // e.x: 03:00
    if( para.size()!=5 )
    {
        EMLogError("Invalid length: %d", para.size());
        return false;
    }

    std::string hourStr(para.c_str(), 2);
    hour = atoi(hourStr.c_str());
    if( hour>23 )
    {
        EMLogError("Invalid hour: %d", static_cast<uint32_t>(hour));
        return false;
    }

    std::string minuteStr(para.c_str()+3, 2);
    min = atoi(minuteStr.c_str());
    if( min>59 )
    {
        EMLogError("Invalid minute: %d", static_cast<uint32_t>(min));
        return false;
    }
    return true;
}

void EutranMgr::locationModeSetting(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;

    bool isEnable = false;
    std::vector<std::string> imsiList;
	std::vector<uint16_t> powerlist;
    LteDuplexMode duplexMode = TDD;
	uint8_t slotId = 0;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_LOC_MODE_ENABLE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            if( strcmp(value, "on")==0 )
            {
                isEnable = true;
            }
            EMLogInfo("LOC mode isEnable %d", isEnable);
        }
        else if( paraType==PARA_TYPE_EUTRAN_LOC_MODE_IMSI_LIST )
        {
            std::string imsiStr(reinterpret_cast<char*>(paraValue), paraLength);
            splitImsi(imsiStr, imsiList);
            EMLogInfo("LOC: IMSI list=%s", imsiStr.c_str());
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU_DUPLEX_MODE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);

            if( strcmp(value, "FDD")==0 )
            {
                EMLogInfo("Duplex mode is FDD");
                duplexMode = FDD;
            }
        }
        else if(paraType==PARA_TYPE_EUTRAN_POWER_LIST)
        {
            if( paraLength%sizeof(uint16_t)!=0 )
            {
                EMLogError("Invalid powerlist parameter length[%d]", paraLength);
                break;
            }
            uint16_t* p16 = reinterpret_cast<uint16_t*>(paraValue);
            for(uint32_t i=0; i<paraLength/2; i++)
            {
                uint16_t pci = p16[i];
                powerlist.push_back(pci);
            }
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
    }
	
    if (slotId != 0)
	{
		BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
		if( ( bbu->isWorking()))
		{
				bbu->buidlAndSendLocModeSetting(isEnable, imsiList);
		}
		setTxPowerDb(slotId, powerlist[slotId -1]);			
		
	}
	else
	{
		for (uint8_t i=1; i<=BbuManager::MAX_BBU_INSTANCES; i++)
		{
			BbuCtrl* bbu = BbuManagerPtr->getBbu(i);
			if( bbu==NULL )
			{
				continue;
			}
			if( duplexMode==bbu->getInstance().getDuplexMode() )
			{
				if ( bbu->isWorking())
				{
					bbu->buidlAndSendLocModeSetting(isEnable, imsiList);
				}
				if (!isEnable)
				{
					setTxPowerDb(i, 127);
				}
				else
				{
					setTxPowerDb(i, powerlist[i -1]);	
				}		
			}
		}
	}
	BbuManagerPtr->setLocationImsi(imsiList);
	BbuManagerPtr->setLocationEnable(duplexMode, isEnable);

    std::vector < WrapperCmdPara > responseParas;
    responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_SUCCESS)));
    responseToSrcModule((processingCmdHdr_.cmdType | 0x10), responseParas);
}


void EutranMgr::BlackListModeSetting(PPARAM pParam, uint32_t len)
{
    EMLogInfo("In Black list mode setting");
    
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;

    //bool isEnable = false;
    uint8_t slotId = 0;
    std::vector<std::string> imsiList;

    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_LOC_MODE_IMSI_LIST )
        {
            std::string imsiStr(reinterpret_cast<char*>(paraValue), paraLength);
            splitImsi(imsiStr, imsiList);
            EMLogInfo("LOC: IMSI list=%s", imsiStr.c_str());
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId is %d", static_cast<uint32_t>(slotId));
        }
    }
/*
    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slotId[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return ;
    }
    
    if( !bbu->buidlAndSendLocModeSetting(true, imsiList) )
    {
        responseFailure();
    }
    else
    {
        responseSuccess();
    }
*/
    for (uint8_t i=1; i<=BbuManager::MAX_BBU_INSTANCES; i++)
    {
        BbuCtrl *bbu = BbuManagerPtr->getBbu(i);
        if (bbu == NULL)
        {
            EMLogError("Fail to get BBU[%d]", static_cast<uint32_t>(i));
            continue;
        }
        
        if (bbu->isWorking())
        {
            if (!bbu->buidlAndSendLocModeSetting(true, imsiList))
            {
                responseFailure();
                return;  
            }

        }
    }
     responseSuccess();
    
}


void EutranMgr::WorkPeriodSetting(PPARAM pParam, uint32_t len)
{
    EMLogInfo("In work Period  setting");
    
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;

    //bool isEnable = false;
    uint8_t  IsPwrOff = 0;

    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_IS_POWER_OFF )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            IsPwrOff = atoi(value);
            EMLogInfo("setting work Period is %d", IsPwrOff);
        }
        else
        {
            responseFailure();
            return;

        }
    }
    
    if (IsPwrOff == 0)
    {
        SnifferMgrPtr->openTxPwer();
    }
    else
    {
        if (!SnifferMgrPtr->isSniffering())
        {
            for (uint8_t i=1; i<=BbuManager::MAX_BBU_INSTANCES; i++)
            {
                BbuCtrl *bbu = BbuManagerPtr->getBbu(i);
                if (bbu == NULL)
                {
                    EMLogError("Fail to get BBU[%d]", static_cast<uint32_t>(i));
                    continue;
                }
        
                if (bbu->isWorking())
                    bbu->buildAndSendTxPowerDb(127);

            }

         }
    }
    responseSuccess();
}


void EutranMgr::startSnifferAuto(const std::vector<uint8_t>& bandList,
                                     const std::vector<EarfcnRangeType>& earfcnRange, 
                                     const std::vector<uint16_t>& pciList)
{
    std::vector < WrapperCmdPara > responseParas;
    if( SnifferMgrPtr->isSniffering() )
    {
        EMLogWarning("Sniffer is ongoing");
        return ;
    }
    
    std::vector<EarfcnRangeType> arfcnRange;
    generageArfcnRange(arfcnRange, bandList, earfcnRange);

    if( arfcnRange.empty() )
    {
        EMLogError("arfcnRange is empty");
        return ;
    }
/*
    if( !SnifferMgrPtr->startSnifferAuto(arfcnRange, &pciList) )
    {
        EMLogError("Fail to start sniffer automatically");
    }*/
}

void EutranMgr::stopSniffer()
{
    SnifferMgrPtr->stopSniffer();

    responseSuccess();
}

void EutranMgr::resetSniffer()
{
    SnifferMgrPtr->resetSniffer();

    responseSuccess();
}

bool EutranMgr::configCell(uint8_t slotId, uint16_t dlArfcn, uint16_t ulArfcn, uint16_t pci, uint16_t tac, 
                    std::vector<uint32_t>& plmnList, 
                    const std::vector<uint16_t>& intraFreqPci, 
                    const std::vector<uint16_t>& interFreq, int16_t* txPwerPtr, bool  isMeasEnable, uint8_t snifferType)
{    
    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        responseFailure();
        return true;
    }

    bbu->setWorkingCellInfo(dlArfcn, ulArfcn, pci, tac, plmnList, txPwerPtr, isMeasEnable);

//    if( FDD==bbu->getInstance().getDuplexMode() )
//    {
//        EMLogInfo("BBU[%d]: FDD, config cell directly", bbu->getInstance().getSlotId());
//        if( !OamManagerPtr->setTrgByOam(true)->configCell(slotId, dlArfcn, ulArfcn, pci, tac, plmn, intraFreqPci, interFreq, txPwerPtr) )
//        {
//            EMLogError("Fail to config cell");
//            EutranMgrPtr->responseFailure();
//        }
 //   }
 //   else
    {
        EMLogInfo("BBU[%d] start sniffer", bbu->getInstance().getSlotId());
        if( SnifferMgrPtr->isSniffering(slotId) )
        {
            EutranMgrPtr->responseFailure();
            return true;
        }
        else
        {
            //std::vector< EarfcnRangeType > range;
           // range.push_back(EarfcnRangeType(dlArfcn, dlArfcn));

            std::vector< EarfcnRangeType > range;
            std::vector<uint16_t>::iterator arfcnBeginIt;
            std::vector<uint16_t>::iterator arfcnEndIt;
            if( !bbu->getSnifferArfcn().empty() )
            {
                EMLogInfo("Num of earfcn is %d", bbu->getSnifferArfcn().size());
                arfcnBeginIt = bbu->getSnifferArfcn().begin();
                arfcnEndIt = bbu->getSnifferArfcn().end();
            }
            for(; arfcnBeginIt!=arfcnEndIt; arfcnBeginIt++)
            {
                EMLogInfo("Sniffer arfcn=%d", *arfcnBeginIt);
                EarfcnRangeType arfcns;
                arfcns.first = *arfcnBeginIt;
                arfcns.second = *arfcnBeginIt;
                range.push_back(arfcns);
            }
            if ( BbuManagerPtr->isLocationMode())
            {
                if( !SnifferMgrPtr->startSnfWithoutPrepareProc(snifferType, slotId, range) )
                {
                    EMLogError("Fail to start sniffer");
                    return false;
                }
            }
            else
            {
                if (range.empty())
                {
                    EMLogInfo("use config dlarfcn");
                    range.push_back(EarfcnRangeType(dlArfcn, dlArfcn));
                }
                if (snifferType == PARA_VALUE_EUTRAN_OAM_SNIFFER)
                {
                    if( !SnifferMgrPtr->startSniffer(OAM_SNF_TRIGGER, slotId, range, NULL) )
                    {
                        EMLogError("Fail to start sniffer");
                        EutranMgrPtr->responseFailure();
                        return false;
                    }
                }
                else
                {
                    if( !SnifferMgrPtr->startSniffer(AUTO_SNF_TRIGGER, slotId, range, NULL) )
                    {
                        EMLogError("Fail to start sniffer");
                        EutranMgrPtr->responseFailure();
                        return false;
                    }
                }
            }

			//different config mode set differnet snf trigger
            SnifferMgrPtr->setAutoCfgCellFlag(true);
        }
    }
    
    return true;
}

bool EutranMgr::UpdateCell(uint8_t slotId, std::vector<uint32_t>* plmnList, uint16_t* tac, uint16_t* earfcn,
                                              bool* measEnablePtr, bool isChangeOperator)
{
    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        responseFailure();
        return true;
    }
    if ( (*plmnList)[0] != 0x46000f )
    
    {
        uint16_t ulArfcn = 0;
        uint16_t dlArfcn = 0;
        if ( BbuManagerPtr->isLocationMode() && !isChangeOperator)
        {
            dlArfcn = bbu->getWorkingDlArfcn();
            ulArfcn = (dlArfcn + 18000);
            
        }
        else
        {
            dlArfcn = *earfcn;
            ulArfcn = *earfcn + 18000;

        }
         
        if( OamManagerPtr->UpdateCell(slotId, plmnList, tac, &dlArfcn, &ulArfcn, measEnablePtr) )
        {
            responseSuccess();
        }
        else
        {
            responseFailure();
        }
    }
    else
   
    {
        uint16_t dlArfcn = 0;
        if ( BbuManagerPtr->isLocationMode() && !isChangeOperator)
        {
            dlArfcn = bbu->getWorkingDlArfcn();
        }
        else
        {
            dlArfcn = *earfcn;
        }
        
        if( OamManagerPtr->UpdateCell(slotId, plmnList, tac, &dlArfcn, NULL, measEnablePtr) )
        {
            responseSuccess();
        }
        else
        {
            responseFailure();
        } 

    }

    return true;
}

void EutranMgr::requestSnifferStatus(uint8_t slotId)
{
    std::vector < WrapperCmdPara > responseParas;
    if( slotId==0 )
    {
        if( SnifferMgrPtr->isSniffering() )
        {
            EMLogInfo("Sniffering");
            responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_SNIFFER_STATUS, static_cast<uint32_t>(PARA_VALUE_EUTRAN_SNIFFER_STATUS_ONGOING)));
        }
        else
        {
            EMLogInfo("Idle");
            responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_SNIFFER_STATUS, static_cast<uint32_t>(PARA_VALUE_EUTRAN_SNIFFER_STATUS_IDLE)));
        }
        responseToSrcModule(CMD_SET_RESPONSE, responseParas);
    }
    else
    {
        if( slotId > BbuManager::MAX_BBU_INSTANCES )
        {
            EMLogError("Slot-id[%d] is out of range", static_cast<uint32_t>(slotId));
            responseFailure();
        }
        else
        {
            if( !SnifferMgrPtr->procedureTrigByOam(true)->requestBbuSnifferStatus(slotId) )
            {
                responseFailure();
            }
        }
    }
}

void EutranMgr::requestSoftwareVersion(uint8_t slotId)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES)
    {
        EMLogError("Invalid slot-id %d", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->buildAndSendSoftwareVerReq() )
    {
        responseFailure();
    }
    else
    {
        OamManagerPtr->setTrgByOam(true);
    }
}

void EutranMgr::requestBbuState(uint8_t slotId)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES)
    {
        EMLogError("Invalid slot-id %d", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->getInstance().isActive() )
    {
        StateReportProcedurePtr->reportState(*bbu, BBU_INACTIVE);

        uint32_t paraCode = PARA_VALUE_EUTRAN_BBU_INVALID;
        std::vector < WrapperCmdPara > responseParas;
        responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_SUCCESS)));
        responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_SLOT_ID, static_cast<uint8_t>(bbu->getInstance().getSlotId())));
        responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_STATE, paraCode));
        responseToSrcModule(CMD_GET_RESPONSE| 0x10, responseParas);
    }

    if( !StateReportProcedurePtr->setBbu(bbu)->start() )
    {
        responseFailure();
    }
    else
    {
        StateReportProcedurePtr->isTrgByOam_ = true;
    }
}

void EutranMgr::rebootBbu(uint8_t slotId, std::string& desc)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES)
    {
        EMLogError("Invalid slot-id %d", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }


    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    OamManagerPtr->setTrgByOam(true);
    bbu->handleCtrlPA(false, BbuCtrl::REBOOT);
}

void EutranMgr::setSyncMode(uint8_t slotId, uint8_t statusCode)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES)
    {
        EMLogError("Invalid slot-id %d", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->buildAndSendSyncModeSetting(statusCode) )
    {
        responseFailure();
    }
    else
    {
        OamManagerPtr->setTrgByOam(true);
    }
}

void EutranMgr::getSyncState(uint8_t slotId)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES)
    {
        EMLogError("Invalid slot-id %d", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->buildAndSendSyncStateReq() )
    {
        responseFailure();
    }
    else
    {
        EMLogInfo("BBU[%d]: Request SYNC state", bbu->getInstance().getSlotId());
        OamManagerPtr->setTrgByOam(true);
    }
}

void EutranMgr::upgradeBbu(uint8_t slotId, std::string& ipAddr, 
                                std::string& fileName, std::string& md5, 
                                std::string& userName, std::string& passwd, uint8_t downMode)
{
    if( slotId==0 || slotId > BbuManager::MAX_BBU_INSTANCES)
    {
        EMLogError("Invalid slot-id %d", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( bbu==NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    if( !bbu->buildAndSendUpgradeReq(ipAddr, fileName, md5, userName, passwd, downMode) )
    {
        responseFailure();
    }
    else
    {
        OamManagerPtr->setTrgByOam(true);
    }
}

void EutranMgr::generageArfcnRange(std::vector<EarfcnRangeType>& range, const std::vector<uint8_t>& bandList, const std::vector<EarfcnRangeType>& earfcnRange)
{
    std::copy(earfcnRange.begin(), earfcnRange.end(), std::back_inserter(range));
    
    uint16_t lowerArfcn = 0;
    uint16_t upperArfcn = 0;
    for(size_t i=0; i<bandList.size(); i++)
    {
        EMLogInfo("band is 0x%x", (uint32_t)bandList[i]);
        if( BandData::getArfcnRangeFromBand(bandList[i], lowerArfcn, upperArfcn) )
        {
            if( lowerArfcn > upperArfcn )
            {
                continue;
            }        
            range.push_back(EarfcnRangeType(lowerArfcn, upperArfcn));
        }
    }
}

void EutranMgr::processScanResult(uint8_t slotId, uint8_t* data, uint32_t length)
{
    if( data==NULL )
    {
        EMLogError("Pointer is NULL");
        responseFailure();
        return;
    }
    BbuCtrl *bbu = BbuManagerPtr->getBbu(slotId);
  

    if( bbu==NULL )
    {
        EMLogError("Fail to found BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    EMLogInfo("BBU[%d]: Report LTE scan result", static_cast<uint32_t>(slotId));
        
    TlvMessage tlvMsg(data, length);
    NmmToX86Protocol_LteScanResultRsp scanRes(tlvMsg);

    std::vector<LteSacnnerResult> result;
    if( !scanRes.unpack(result) )
    {
        EMLogWarning("Fail to unpack NmmToX86Protocol_LteScanResultRsp");
        responseFailure();
        return;
    }

    std::vector < WrapperCmdPara > reportParas;
    reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_SLOT_ID, slotId));
    
    for(size_t i=0; i<result.size(); i++)
    {        
        uint8_t paraBuf[1024] = {0};
        memset(&paraBuf[0], 0, sizeof(paraBuf));

        memcpy(paraBuf, &result[i].plmn, sizeof(result[i].plmn));
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_PLMN_ID, sizeof(result[i].plmn), paraBuf));

        uint16_t v16 = result[i].tac;
     reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_TAC, v16));

        v16 = result[i].pci;
     reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_PCI, v16));

        v16 = result[i].earfcn;
     reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_DL_ARFCN, v16));

        int32_t i32 = result[i].rsrq;
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_RSRQ, i32));

        i32 = result[i].rsrp;
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_RSRP, i32));

        i32 = result[i].rssi;
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_SNIFFER_RSSI, i32));

        i32 = result[i].priority;
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_PRIORITY, i32));
    }
    EutranMgrPtr->reportScanResult(CMD_EVT_EUTRAN_LTE_SCAN_RES, reportParas);
    responseSuccess();
}

void EutranMgr::processUeId(uint8_t slotId, uint8_t* data, uint32_t length)
{
    if( data==NULL )
    {
        EMLogError("Pointer is NULL");
        return;
    }
    BbuCtrl *bbu = BbuManagerPtr->getBbu(slotId);
    bbu->setRecvImsi(true);
    std::vector<UeIdTuple> ueIdRecords;
    TlvMessage tlvMsg(data, length);
    NmmToX86Protocol_UeidReport ueId(tlvMsg);
    if( !ueId.unpack(ueIdRecords) )
    {
        EMLogWarning("Fail to unpack NmmToX86Protocol_UeidReport");
        return;
    }

    std::vector< std::pair<std::string, std::string> > ueIdArray;
    ueIdArray.reserve(ueIdRecords.size());

    std::string imsi, imei;
    for(size_t i=0; i<ueIdRecords.size(); i++)
    {
        char* tmpPtr = reinterpret_cast<char*>(&ueIdRecords[i].ueId_[0]);
        imsi.assign(tmpPtr, UeIdTuple::LENGTH_OF_IMSI);
        imei.assign(tmpPtr+UeIdTuple::LENGTH_OF_IMSI, UeIdTuple::LENGTH_OF_IMEI);

        EMLogDebug("BBU[%d]: IMSI:%s, IMEI:%s", static_cast<uint32_t>(slotId), imsi.c_str(), imei.c_str());
        ueIdArray.push_back(std::make_pair<std::string, std::string>(imsi, imei));
    }
    
    EMLogDebug("Size of ueid[%d]", ueIdRecords.size());

    time_t t = time(NULL);

    for(size_t i=0; i<ueIdArray.size(); i++)
    {
        std::vector < WrapperCmdPara > reportParas;
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_SLOT_ID, slotId));
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_TIME, static_cast<uint64_t>(t)));


        uint8_t tmpbuf1[128] = {0};
        memset(&tmpbuf1[0], 0, sizeof(tmpbuf1));
        uint8_t tmpbuf2[128] = {0};
        memset(&tmpbuf2[0], 0, sizeof(tmpbuf2));

        std::string& refImsi = ueIdArray[i].first;
        std::string& refImei = ueIdArray[i].second;
        memcpy(&tmpbuf1[0], refImsi.c_str(), refImsi.length());
        tmpbuf1[refImsi.length()] = '\0';
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_UEID_IMSI, refImsi.length()+1, &tmpbuf1[0]));


        memcpy(&tmpbuf2[0], refImei.c_str(), refImei.length());
        tmpbuf2[refImei.length()] = '\0';
        reportParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_UEID_IMEI, refImei.length()+1, &tmpbuf2[0]));

        EutranMgrPtr->reportUeId(CMD_EVT_EUTRAN_UEID, reportParas);
    }
}

bool EutranMgr::isProcessingCmd()
{
    if( processingMsgSrcId_!=0 )
    {
        EMLogInfo("Processing CMD: 0x%x from %d", processingCmdHdr_.cmdCode, processingMsgSrcId_);
    }
    return processingMsgSrcId_!=0;
}

void EutranMgr::handleCmdProcessTimeout()
{
    EMLogWarning("process command[cmdType=%d, cmdCode=0x%x] time out", processingCmdHdr_.cmdType, processingCmdHdr_.cmdCode);
    processingMsgSrcId_ = 0;
}

void EutranMgr::timerHeartBeat()
{
    std::vector < WrapperCmdPara > reportParas;
    reportParas.push_back(WrapperCmdPara(PARA_TYPE_SYSMONITOR_MODULE_STATE, static_cast<uint32_t>(PARA_VALUE_SYSMONITOR_MODULE_OK)));
    EutranMgrPtr->reportToModule(MODULE_SYSMONITOR,  CMD_CODE_SYSMONITOR_HEARTBEAT  ,reportParas);   
    EutranTimerPtr->queue(heartBeatVal_, &TimerHeartBeat_);
}


void EutranMgr::handleTimerTick()
{
    EutranTimerPtr->handleTick();
}

void EutranMgr::processUeRedirectCommand(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t slotId = 0;
    uint32_t operCode = 0;
    uint8_t* ranType = NULL;
    uint8_t* band = NULL;
    std::vector<uint16_t>* arfcnList = NULL;
    std::vector<std::string>* imsiList = NULL;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_EUTRAN_UE_REDIRECT_OPER_CODE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            operCode = *(reinterpret_cast<uint32_t*>(paraValue));
            EMLogInfo("operCode2: %d", operCode);
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            slotId = atoi(value);
            EMLogInfo("slotId: %d", static_cast<uint32_t>(slotId));
        }
        else if( paraType==PARA_TYPE_RAN_TYPE )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            ranType = new uint8_t;
            if( ranType!=NULL )
            {
                *ranType = atoi(value);
                EMLogInfo("ranType: %d", *ranType);
            }
        }
        else if( paraType==PARA_TYPE_EUTRAN_SNIFFER_BAND )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            band = new uint8_t;
            if( band!=NULL )
            {
                *band = atoi(value);
                EMLogInfo("band: %d", static_cast<uint32_t>(*band));
            }
        }
        else if( paraType==PARA_TYPE_EUTRAN_ARFCN_LIST )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            arfcnList = new std::vector<uint16_t>;
            if( arfcnList!=NULL )
            {
                convertToArfcnList(reinterpret_cast<const char*>(paraValue), paraLength, *arfcnList);
                EMLogInfo("num of arfcnList: %d", arfcnList->size());
            }
        }
        else if( paraType==PARA_TYPE_EUTRAN_LOC_MODE_IMSI_LIST )
        {
            char value[2048];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);
            imsiList = new std::vector<std::string>;
            if( imsiList!=NULL )
            {
                std::string imsiStr(value);
                splitImsi(imsiStr, *imsiList);
                EMLogInfo("Num of imsiList is %d", imsiList->size());
            }
        }
    }

    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        responseFailure();
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    if( !bbu->getInstance().isActive() )
    {
        EMLogInfo("BBU[%d]:in inactive", bbu->getInstance().getSlotId());
        responseFailure();
        return;
    }
    if( !bbu->buildAndSendUeRedire(operCode==PARA_VALUE_EUTRAN_UE_REDIRECT_ON?true:false, ranType, band,  arfcnList, imsiList) )
    {
        EMLogError("BBU[%d]: Fail to build UE redirect msg", bbu->getInstance().getSlotId());
        responseFailure();
        return;
    }

    OamManagerPtr->setTrgByOam(true);
}

void EutranMgr::processShowBbuCommand()
{
    std::vector<WrapperCmdPara> paras;

    std::stringstream ss;

    for(uint8_t slotId=1; slotId<=BbuManager::MAX_BBU_INSTANCES; slotId++)
    {
        BbuCtrl* ctrl = BbuManagerPtr->getBbu(slotId);
        if( ctrl==NULL )
        {
            EMLogError("NULL pointer");
            continue;
        }

        struct in_addr in;
        in.s_addr = ctrl->getInstance().getBbuIpAddress();
        ss << "BBU[" << static_cast<uint32_t>(slotId) << "]: ip[" << inet_ntoa(in) << "]; ";
        ss << "status[";

        if( ctrl->getInstance().isActive() )
        {
            ss << "Active]; ";
        }
        else
        {
            ss << "Deactive]; ";
        }

        ss << "DuplexMode[";
        if( ctrl->getInstance().getDuplexMode()==TDD )
        {
            ss << "TDD]; ";
        }
        else
        {
            ss << "FDD]; ";
        }

        ss << "TelecomOperator[";
        if( ctrl->getInstance().getTeleOperator()==CHINA_MOBILE )
        {
            ss << "CHINA_MOBILE]; ";
        }
        else if( ctrl->getInstance().getTeleOperator()==CHINA_TELECOM )
        {
            ss << "CHINA_TELECOM]; ";
        }
        else
        {
            ss << "CHINE_UNICOM]; ";
        }

        ss << "BandSupport[";
        std::set<uint8_t> band;
        ctrl->getInstance().getSupportedBands(band);

        for(std::set<uint8_t>::iterator it=band.begin(); it!=band.end(); it++)
        {
            ss << static_cast<uint32_t>(*it) << " ";
        }
        ss << "]\n";
    }
    std::string strInfo = ss.str();
    paras.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_INFO_STR, strInfo.length(), reinterpret_cast<uint8_t*>(const_cast<char*>(strInfo.c_str()))));
    responseToSrcModule(CMD_GET_RESPONSE, paras);
}

void EutranMgr::bbuPowerReset(uint8_t slotId)
{
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        return;
    }
    
    std::vector<WrapperCmdPara> paras;
    paras.push_back(WrapperCmdPara(PARA_TYPE_PM_GPIO_CTRL_PIN, slotId));
    responseToModule(MODULE_PM, MSG_TYPE_COMMAND, CMD_SET, CMD_CODE_PM_RESTART, 0, paras);
}

void EutranMgr::controlPA(uint8_t paId, bool isOn)
{
    std::vector<WrapperCmdPara> paras;
    paras.push_back(WrapperCmdPara(PARA_TYPE_PA_ADDR, paId));
    
    if (isOn)
    {
        EMLogWarning("try to open PA[%d]", paId);
        responseToModule(MODULE_PA, MSG_TYPE_COMMAND, CMD_SET, CMD_CODE_PA_SWITCH_ON, 0, paras);
    }
    else
    {
        EMLogWarning("try to close PA[%d]", paId);
        responseToModule(MODULE_PA, MSG_TYPE_COMMAND, CMD_SET, CMD_CODE_PA_SWITCH_OFF, 0, paras);
    }

}

void EutranMgr::handlePaOnResponse(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t paId = 0;
    uint32_t result = PARA_VALUE_ERROR_GENERAL_ERROR;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_RESULT )
        {
            result = *(uint32_t *)(paraValue);
        }
        else if (paraType == PARA_TYPE_PA_ADDR)
        {
            paId = *(uint8_t *)paraValue; 
        }
    }
    
    if (result != PARA_VALUE_ERROR_NO_ERROR)
    {
        EMLogWarning("pa control reponse is error");
        return;
    }

    for (uint8_t i=1; i<=BbuManager::MAX_BBU_INSTANCES; i++)
    {
        BbuCtrl* bbu = BbuManagerPtr->getBbu(i);
        if( bbu==NULL )
        {
            continue;
        }
        if (bbu->BbuIsRegisted())
        {
            if (bbu->getPaId() == paId)
            {
                bbu->handleCtrlPaResult(true);
                EMLogNotice("open pa[%d] success", static_cast<uint32_t>(paId));

            }
        
        }
    }

}

void EutranMgr::handlePaOffResponse(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint8_t paId = 0;
    uint32_t result = PARA_VALUE_ERROR_GENERAL_ERROR;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {
        if( paraType==PARA_TYPE_RESULT )
        {
            result = *(uint32_t *)(paraValue);
        }
        else if (paraType == PARA_TYPE_PA_ADDR)
        {
            paId = *(uint8_t *)paraValue; 
        }
    }
    
    if (result != PARA_VALUE_ERROR_NO_ERROR)
    {
        EMLogWarning("pa control reponse is error");
        return;
    }

    for (uint8_t i=1; i<=BbuManager::MAX_BBU_INSTANCES; i++)
    {
        BbuCtrl* bbu = BbuManagerPtr->getBbu(i);
        if( bbu==NULL )
        {
            continue;
        }
        if (bbu->BbuIsRegisted())
        {
            if (bbu->getPaId() == paId)
            {
                bbu->handleCtrlPaResult(false);
                EMLogNotice("close pa[%d] success", static_cast<uint32_t>(paId));

            }
        
        }
    }
}



void EutranMgr::setBbuConfiged(uint8_t slotId)
{
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        return;
    }

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    bbu->registerBbu(slotId);
	bbu->indicateDeactive();
    bbu->handleCtrlPA(false, BbuCtrl::REBOOT);
}

void EutranMgr::splitImsi(std::string& imsiStr, std::vector<std::string>& imsiList)
{
    std::string delim = ";";
    size_t last = 0;  
    size_t index = imsiStr.find_first_of(delim, last);  
    while (index != std::string::npos)  
    {  
        imsiList.push_back(imsiStr.substr(last,index-last));  
        last = index+1;  
        index = imsiStr.find_first_of(delim,last);  
    }  
    if (index-last>0)  
    {  
        imsiList.push_back(imsiStr.substr(last,index-last));  
    }  
}

bool EutranMgr::convertToArfcnList(const char* paraValue, uint32_t paraLength, std::vector<uint16_t>& arfcnList)
{
    if( paraValue==NULL ||paraLength==0 )
    {
        EMLogError("paraValue is NULL[%d] or length is 0[%d]", paraValue==NULL, paraLength==0);
        return false;
    }
    uint32_t startIndex = 0;
    uint32_t endIndex = 0;
    uint16_t arfcn = 0;
    for(uint32_t i=0; ;i++, endIndex = i)
    {
        if( i==paraLength )
        {
            std::string s(&paraValue[startIndex], endIndex-startIndex);
            arfcn = atoi(s.c_str());
            startIndex = i+1;
            arfcnList.push_back(arfcn);
            EMLogInfo("arfcn=%d", arfcn);
            break;
        }
        else if( paraValue[i]==',' )
        {
            if( endIndex==startIndex )
            {
                continue;
            }
            std::string s(&paraValue[startIndex], endIndex-startIndex);
            arfcn = atoi(s.c_str());
            arfcnList.push_back(arfcn);
            EMLogInfo("arfcn=%d", arfcn);
            startIndex = i+1;
        }
        else if( paraValue[i]>'9' || paraValue[i]<'0' )
        {
            EMLogError("Invalid parameter[%d]: %c", i, paraValue[i]);
            return false;
        }
        
    }
    return true;
}

void EutranMgr::setBbuSnfArfcn(uint8_t slotId, std::string& arfcnPara)
{
    if( !BbuManagerPtr->isSlotIdValid(slotId) )
    {
        return;
    }
    std::string delim = ",";
    std::vector<uint16_t> arfcnList;
    unsigned last = 0;
    unsigned index = arfcnPara.find_first_of(delim, last);
    while(index != std::string::npos)
    {
        arfcnList.push_back(atoi(arfcnPara.substr(last,index-last).c_str()));
        last = index+1;
        index = arfcnPara.find_first_of(delim,last);
    }

    if(index-last > 0)
    {
        arfcnList.push_back(atoi(arfcnPara.substr(last,index-last).c_str()));
    }
    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    bbu->setSnifferArfcn(arfcnList);
}

void EutranMgr::locationEnableSetting(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    bool locationEnable = false;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {

        if( paraType==PARA_TYPE_EUTRAN_LOCATION_MODE_ENABLE )
        {
           int32_t  enable = 0;     
           enable = *(reinterpret_cast<uint32_t*>(paraValue));
           EMLogInfo("location enable : %d", enable);

           if (enable == 1)
           {
               locationEnable = true;
           }
        }
    }
    BbuManagerPtr->setLocationMode(locationEnable);
    responseSuccess();
}


void EutranMgr::setScanMode(PPARAM pParam, uint32_t len)
{
    UNPACK_RESULT uprc;
    uint32_t paraType;
    uint32_t paraLength;
    uint8_t* paraValue = NULL;
    
    uint32_t sec = 0;

    std::string dlArfcnStr;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    {

        if( paraType==PARA_TYPE_EUTRAN_SCAN_PERIOD )
        {
           sec = *(reinterpret_cast<uint32_t*>(paraValue));
           EMLogInfo("Scan sec: %d", sec);
        }
    }


    for( uint8_t slotId = 1; slotId > BbuManager::MAX_BBU_INSTANCES; slotId++)
    {
      
        BbuCtrl* bbuPtr = BbuManagerPtr->getBbu(slotId);
        if( bbuPtr==NULL )
        {
            continue;
        }
        
        if (bbuPtr->getInstance().isActive() )
        {
            bbuPtr->buildAndSendScanMode(bbuPtr->getSnifferArfcn(), sec);
        }
      
        

        if( sec==0 )
        {
            EMLogInfo("Close scan mode");
            uint16_t tac = bbuPtr->getWorkingTac();
        
            OamManagerPtr->UpdateCell(slotId, NULL,  &tac, NULL, NULL, NULL);
            
        }               
    }
    
    responseSuccess();
}

void EutranMgr::changBbuOperator(int32_t OperatorType ,uint8_t slotId)
{
   BbuCtrl* bbuPtr = BbuManagerPtr->getBbu(slotId);  
   bbuPtr->getInstance().changTeleOperator(OperatorType); 
}

void EutranMgr::setPlmnIdList(uint8_t slotId, std::vector<uint32_t> &plmnList)
{

    BbuCtrl* bbu = BbuManagerPtr->getBbu(slotId);
    bbu->setWorkingPlmnList(plmnList);
}

void splitPlmn(std::string& s, const std::string& delim, std::vector<std::string> *ret)
{
    unsigned last = 0;
    unsigned index = s.find_first_of(delim, last);
    while(index != std::string::npos)
    {
        ret->push_back(s.substr(last,index-last));
        last = index+1;
        index = s.find_first_of(delim,last);
    }

    if(index-last > 0)
    {
        ret->push_back(s.substr(last,index-last));
    }
}

void EutranMgr::changTeleOperator(PPARAM pParam, uint32_t len)

{
    
    UNPACK_RESULT uprc;
    
    std::vector < WrapperCmdPara > responseParas;
    
    uint32_t paraType;
    
    uint32_t paraLength;
    
    uint8_t* paraValue = NULL;
    
    bool isParaValid = true;
    
    int32_t operatorType = 0;
    
    uint8_t slotId = 0;
        
    std::vector<uint32_t> plmnList;
    
    uint16_t tac = 0;
    
    uint16_t* tacPtr = NULL;
    
    uint16_t earfcn = 0;
    
    uint16_t* earfcnPtr = NULL;

    std::string snfArfcnParaBbu6;
	std::string snfArfcnParaBbu7;
    while((uprc=CM_paraUnpackPara(&pParam, &len, &paraType, &paraLength,&paraValue)) == UNPACK_OK)
    
    {
       
        if( paraType==PARA_TYPE_EUTRAN_TAC )
        
        {
            
            char value[128];
            
            memset(value, '\0', sizeof(value));
            
            memcpy(value, paraValue, paraLength);
            
            tac = atoi(value);
            
            tacPtr= &tac;
            
            EMLogInfo("tac=%d", tac);
        
        }
        
        else if(paraType==PARA_TYPE_EUTRAN_DL_ARFCN )
        
        {
            
            char value[128];
            
            memset(value, '\0', sizeof(value));
            
            memcpy(value, paraValue, paraLength);
            
            earfcn = atoi(value);
            
            earfcnPtr= &earfcn;
            
            
            EMLogInfo("earfcn=%d", earfcn);
        
        }
        
        else if(paraType==PARA_TYPE_EUTRAN_BBU_SLOT_ID )
        
        {
            
            char value[128];
            
            memset(value, '\0', sizeof(value));
            
            memcpy(value, paraValue, paraLength);
            
            slotId = atoi(value);
        
        }
        
        else if( paraType==PARA_TYPE_EUTRAN_BBU_OPERATOR )
        
        {
            
            char value[128];
            
            memset(value, '\0', sizeof(value));
            
            memcpy(value, paraValue, paraLength);
            
            operatorType = atoi(value);
            
            EMLogInfo("operator=%d", operatorType);
        
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU6_DL_ARFCN )
        {
            snfArfcnParaBbu6.assign(reinterpret_cast<char*>(paraValue), paraLength);
            EMLogInfo("BBU[6] snfArfcnRange=%s", snfArfcnParaBbu6.c_str());
        }
        else if( paraType==PARA_TYPE_EUTRAN_BBU7_DL_ARFCN )
        {
            snfArfcnParaBbu7.assign(reinterpret_cast<char*>(paraValue), paraLength);
            EMLogInfo("BBU[7] snfArfcnRange=%s", snfArfcnParaBbu7.c_str());
        }

        else if( paraType==PARA_TYPE_EUTRAN_PLMN_ID )
        {
            char value[128];
            memset(value, '\0', sizeof(value));
            memcpy(value, paraValue, paraLength);

            std::string delim(",");
            std::string s(value);
            std::vector<std::string> plmnStr;
            splitPlmn(s, delim, &plmnStr);

            for(size_t i=0; i<plmnStr.size(); i++)
            {
                if (plmnStr[i].find("460") == std::string::npos)
                    continue;
				plmnStr[i] += 'F';
                EMLogInfo("set plmnid: %s\n", plmnStr[i].c_str());
                plmnList.push_back(strtol(plmnStr[i].c_str(), NULL, 16));   
            }
            if (plmnList.size() == 0)
                isParaValid = false;
        }
        else
        
        {
            
            EMLogError("Unknown paraType[%d]", paraType);
            
            isParaValid = false;
        
        }
        

        if( !isParaValid )
        
        {
            
            EMLogError("paraType[0x%x] is invalid", paraType);
                                
            
            responseParas.push_back(WrapperCmdPara(PARA_TYPE_RESULT, static_cast<uint32_t>(PARA_VALUE_RESULT_FAILED)));
            
            responseParas.push_back(WrapperCmdPara(PARA_TYPE_ERROR_CODE, static_cast<uint32_t>(PARA_VALUE_ERROR_INVALID_PARAVALUE)));
            
            responseToSrcModule(CMD_SET_RESPONSE, responseParas);

            
            break;
        
        }
    
    }
	slotId = 6;
    BbuCtrl *bbu = BbuManagerPtr->getBbu(slotId);
    if ( bbu == NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

    changBbuOperator(operatorType, 6);
    setBbuSnfArfcn(6,  snfArfcnParaBbu6);
	setPlmnIdList(6, plmnList);
    changBbuOperator(operatorType, 7);
    setBbuSnfArfcn(7,  snfArfcnParaBbu7);
	setPlmnIdList(7, plmnList);
	uint16_t Pearfcn = *(bbu->getSnifferArfcn().begin());
    bbu->setWorkingDlArfcn(Pearfcn);
	bool updateCell = false;
    if ( bbu->getInstance().isActive() )
    {	
		UpdateCell(6, &plmnList, tacPtr, &Pearfcn, &updateCell, true);
       

    }
    slotId = 7;
    bbu = BbuManagerPtr->getBbu(slotId);
    if ( bbu == NULL )
    {
        EMLogError("Fail to get BBU from slot-id[%d]", static_cast<uint32_t>(slotId));
        responseFailure();
        return;
    }

 	Pearfcn = *(bbu->getSnifferArfcn().begin());
    bbu->setWorkingDlArfcn(Pearfcn);

    if ( !bbu->getInstance().isActive() )
    {
        responseSuccess();
        EMLogInfo("bbu is not active so don't send updateCell to slot-id [%d]", static_cast<uint32_t>(slotId));
        return;
    }
    UpdateCell(7, &plmnList, tacPtr, &Pearfcn, &updateCell, true);
   
 }

 void EutranMgr::reportUsingEarfcn(uint32_t slotId, uint16_t earfcn)
 {
    EMLogInfo("Report earfcn BBU[%d] to %d", slotId, earfcn);
    std::vector < WrapperCmdPara > responseParas;
    responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_BBU_SLOT_ID, static_cast<uint8_t>(slotId)));
    responseParas.push_back(WrapperCmdPara(PARA_TYPE_EUTRAN_DL_ARFCN, earfcn));
    EutranMgrPtr->reportInfo(CMD_EVT_EUTRAN_REPORT_BBU_EARFCN, responseParas);
 }
